package eva.savant.business.administrador.view

import eva.savant.businessobject.ad.Transaccion
import eva.savant.businessobject.ad.Menu
import eva.savant.businessobject.ad.Rol
import eva.savant.core.view.Bean

import org.primefaces.model.TreeNode
import org.primefaces.model.DefaultTreeNode
import org.primefaces.event.NodeSelectEvent
import org.primefaces.event.SelectEvent
import javax.faces.bean.ManagedBean
import javax.faces.bean.SessionScoped
import javax.annotation.PostConstruct

@SessionScoped
@ManagedBean(name = 'IMRol')
class IMRol extends Bean {

  String nombre

  List<Hoja> lsHoja; Hoja selectedHoja

  TreeNode root, cutNode, selectedNode

  @PostConstruct
  public void cleanTree() {

    nombre= null

    entity = new Rol()

    root = new DefaultTreeNode(new Hoja('00','Root',null, null), null); selectedNode = cutNode = null

    lsHoja= toLsHoja(find(Transaccion.class,'sistema.id=? order by tipo, id',sistema.id))
  }

  public List<Hoja> toLsHoja(List<Transaccion> lsTransaccion) {

    def list= new ArrayList<Hoja>()

    for (transaccion in lsTransaccion)

    list.add(new Hoja(transaccion.id , transaccion.nombre, transaccion.codigo, transaccion.tipo))

    return list
  }

  public void mergeTree() {

    def rol= root.children[0]

    def menu= get(Menu.class,rol.data.id)

    removeNodes(menu.lsMenu)

    saveNodes(rol.children)

    addInfoMessage 'Se modifico correctamente el Rol ' + menu.id; cleanTree()
  }

  public void onTransaccionSelect(SelectEvent event) {

    def hoja= (Hoja) event.object

    if(root.childCount == 0 && hoja.tipo == 0) {

      def menu= get(Menu.class,hoja.id)

      def rol= new DefaultTreeNode('folder',hoja,root)

      if(menu != null && menu.padre == null) createNodes(rol, menu.lsMenu)

      lsHoja.remove(hoja)

    } else if(selectedNode?.type?.equals('folder') && !selectedNode.parent != null && hoja.tipo != 0) {

      lsHoja.remove(hoja); new DefaultTreeNode('document',hoja,selectedNode) }

  }

  public void cutNode() {

    cutNode= selectedNode
  }

  public void pasteNode() {

    if(selectedNode?.type?.equals('folder') && !selectedNode.equals(cutNode)) cutNode.parent= selectedNode

    cutNode= null
  }

  public void deleteNode() {

    if(selectedNode?.childCount > 0) return


    if(selectedNode?.type?.equals('document') || root.children[0].childCount == 0)

    lsHoja.add((Hoja)selectedNode.data)


    selectedNode.children.clear()

    selectedNode.parent.children.remove(selectedNode)

    selectedNode.parent= null

    selectedNode = null
  }

  public void onNodeSelect(NodeSelectEvent event) {

    nombre= selectedNode?.type?.equals('folder') &&

            selectedNode?.parent?.parent != null? event.treeNode.data.nombre : null
  }

  public void createFolder() {

    if(selectedNode?.type?.equals('folder') && nombre?.length() > 0)

    new DefaultTreeNode('folder',new Hoja(null,nombre,null,null),selectedNode)


    nombre= null
  }

  public void updateFolder() {

    if(selectedNode?.type?.equals('folder') && nombre?.length() > 0 && selectedNode.parent.parent != null)

    selectedNode.data.nombre= nombre

    nombre= null
  }

  public void saveNodes(List<TreeNode> lsNode) { //recursive

    for(int i=0; i<lsNode.size(); i++) {

    def node= lsNode[i]

    def id=  i < 10? '0'+i : i

    node.data.id= node.parent.data.id + id


    def transaccion= node.type.equals('document')? get(Transaccion.class,sociedad.id + node.data.codigo) : null

    def parent= new Menu(); parent.id= node.parent.data.id


    merge(new Menu((String)node.data.id,parent,sistema.id,transaccion,(String)node.data.nombre,ALTA,sociedad.id,usuario.id))

    saveNodes(node.children) }

  }

  public void createNodes(DefaultTreeNode parent, Collection<Menu> lsMenu){ //recursive

   for(menu in lsMenu) {

   String codigo= menu.transaccion != null ? menu.transaccion.codigo : null

   Integer tipo = menu.transaccion != null ? menu.transaccion.tipo   : null


   def hoja= new Hoja(menu.id,menu.nombre,codigo,tipo); removeHoja(hoja.codigo)

   def node= new DefaultTreeNode(menu.transaccion == null? 'folder' : 'document', hoja, parent)


   createNodes(node, menu.lsMenu) }
  }

  public void removeNodes(Collection<Menu> lsMenu) { //recursive

    for(menu in lsMenu) {

    removeNodes(menu.lsMenu)

    menu= entityService.getReference(Menu.class,menu.id)

    delete(menu) }
  }

  public void removeHoja(String hojaCod) {

    for(hoja in lsHoja) if(hoja.codigo.equalsIgnoreCase(hojaCod)) { lsHoja.remove(hoja); return }
  }

  class Hoja {

    String id

    String nombre

    String codigo

    Integer tipo

    public Hoja(String id, String nombre, String codigo, Integer tipo) {

      this.id= id

      this.nombre= nombre

      this.codigo= codigo

      this.tipo= tipo
    }

  }


  public void cleanEntity() {

    form= false

    dialog= true

    entity = new Rol()
  }

  public List findLsEntity() {

    dialog= form= false

    return find(Rol.class,'')
  }

  public boolean mergeEntity(Object entity) { entity= (Rol) entity

    form= dialog= false


    def id= getNextCode(Rol.class)

    def tr= get(Transaccion.class, entity.id + ''); id= tr != null? tr.codigo : id


    def transaccion= merge( new Transaccion(sociedad.id + id, sistema, id, entity.nombre,

                                            '/business/splash.xhtml', 0, ALTA, sociedad.id, usuario.id) )

    id= transaccion.id

    def menu= merge(new Menu(id, null, sistema.id, transaccion, transaccion.nombre, ALTA, sociedad.id, usuario.id))

    this.entity= merge(new Rol(id, menu, sistema, transaccion.codigo, transaccion.nombre, ALTA, sociedad.id, usuario.id))


    lsEntity= find(Rol.class,''); cleanTree(); return true
  }

  public void editEntity(Object id) {

    dialog= true; form= false

    entity= get(Rol.class, id)
  }

  public void removeEntity(Object entity) {

    dialog= form= false;

    def t= get(Transaccion.class,entity.id)

    t.operacionId= BAJA; remove(t); remove(entity)

    lsEntity= find(Rol.class,''); cleanTree()
  }

}